#include "client.h"

#include "nodecollector.h"

#include <iostream>
using std::cout;
using std::endl;
using std::string;

#include <Poco/Types.h>
using Poco::UInt64;

#include "command/node/batchputcommand.h"
#include "command/node/batchgetcommand.h"
using namespace Commands;

Client::Client()
	: _master(new Master())
{
}

Client::~Client()
{
}

void Client::uploadFiles(vector<File> files )
{
	map<string, File> batch;
	for (vector<File>::iterator it = files.begin(); it != files.end(); ++it)
	{
		batch[it->path()] = *it;
		cout << "Client :: Uploading '" << it->path() << "'" << endl;
		_master->put(it->path());
	}
	cout << "Client :: Creating BatchPutCommand" << endl;
	BatchPutCommand cmd(batch);
	cout << "Client :: Created BatchPutCommand" << endl;
	_master->executeCommand(&cmd);
}

void Client::downloadFiles(vector<File> files )
{
	BatchGetCommand::Files batch;
	for (vector<File>::iterator it = files.begin(); it != files.end(); ++it)
	{
		batch[it->path()] = *it;
	}
	cout << "Client :: Creating BatchGetCommand" << endl;
	BatchGetCommand cmd(batch);
	cout << "Client :: Created BatchGetCommand" << endl;
	_master->executeCommand(&cmd);
	for (vector<File>::iterator it = files.begin(); it != files.end(); ++it)
	{
		bool found = _master->get(it->path(), *it);
		cout << "Client :: Downloading '" << it->path() << "' " << (found ? "OK" : "FAILED") << endl;
	}
}

void Client::connect(string ringname)
{
	NodeCollector col(SocketAddress("234.42.35.70",42069), ringname);
	col.run();
	SocketAddress nodeAddr = col.node();
	
	cout << "Client :: Going to join " << nodeAddr.toString() << endl;
	_master->join(nodeAddr.host().toString(), nodeAddr.port());
}

void Client::disconnect()
{
	cout << "Client :: Disconnect" << endl;
	_master->leave();
}
